package com.xinan.system.curd;

import com.jfinal.aop.Before;
import com.jfinal.core.BaseController;
import com.jfinal.core.Const;
import com.jfinal.core.Controller;
import com.jfinal.ext.interceptor.SearchSql;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.StringKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.ehcache.CacheKit;
import com.jfinal.render.JsonRender;
import com.xinan.utils.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * CommonController
 */
public class CurdController extends BaseController {
    private Logger log = LoggerFactory.getLogger(getClass());
    public void index() {
        String tbName = getPara(0);
        String path = getPara(1);
        String view = getPara(2);
        if(buildView(tbName, "")){
            if (StringKit.notBlank(path) && StringKit.notBlank(view)) {
                render(path + "/" + view + ".html");
            } else {
                render("/WEB-INF/views/common/curd.html");
            }
        }else {
            String msg = "该业务表还没有生成对应的增删改查配置，请先通知管理员进行配置！";
            log.info(msg);
            renderText(msg);
        }
    }

    protected boolean buildView(String tbName, String fields){
        CurdMeta curd = CurdMeta.dao.findByTableName(tbName);
        if (curd != null) {
            List<TableMeta> queryList = TableMeta.dao.findByFields(tbName, curd.getQueryFields());
            List<TableMeta> listList = TableMeta.dao.findByFields(tbName, curd.getListFields());
            List<TableMeta> cuList = TableMeta.dao.findByFields(tbName, curd.getCuFields());
            //根据编辑配置的外键关系，生成对应的下拉树组件url
            List<Map<String, String>> fdsList = buildFieldsFk(cuList);
            setAttr("fdsList", fdsList);
            //根据查询配置的外键关系，生成对应的下拉树组件url
            List<Map<String, String>> qFdsList = buildFieldsFk(queryList);
            setAttr("qFdsList", qFdsList);
            //如果字段关联有外键，则提取出其关联的外键集合，以便在前段进行翻译
            for (TableMeta t : listList) {
                if (StringKit.notBlank(t.getFkTable()) && StringKit.notBlank(t.getFkId())
                        && StringKit.notBlank(t.getFkName())) {
                    String sql = "select ";
                    if(StringKit.notBlank(fields)){
                        sql += fields + ",";
                    }
                    sql += t.getFkId() + " as id," + t.getFkName() + " as text from " + t.getFkTable();
                    if (StringKit.notBlank(t.getFkWhere())) {
                        sql += " where " + t.getFkWhere();
                    }
                    List<Record> recordList = Db.find(sql);
                    t.put("data", JsonKit.toJson(recordList));
                }
            }
            //页面元素加载所需数据
            setAttr("query", queryList);
            setAttr("list", listList);
            setAttr("cu", cuList);
            setAttr("tbName", tbName);
            return true;
        }else{
            String msg = "该业务表还没有生成对应的增删改查配置，请先通知管理员进行配置！";
            log.info(msg);
            renderText(msg);
            return false;
        }
    }

    /**
     * 在增加了SearchSql拦截之后，就可以根据页面的配置信息
     * 自动装配查询语句，并放入request中，可以通过getAttr(Const.SEARCH_SQL)函数获取到
     * 根据实际需要自动组装到sql语句中
     */
    @Before(SearchSql.class)
    public void query() {
        int pageNumber = getParaToInt("page");
        int pageSize = getParaToInt("rows");
        String tbName = getPara(0);
        String sqlExp = "from " + tbName;
        String where = getAttr(Const.SEARCH_SQL);
        if(StringKit.notBlank(where)){
            sqlExp += " where " + where;
        }
        //加入排序
        String sort=getPara("sort");
        String order="";
        if(StringKit.notBlank(sort)) {
              order="  order by "+sort;
        }
        
        Page<Record> page = Db.paginate(pageNumber, pageSize, "select *", sqlExp+order);
        Map root = new HashMap();
		root.put("total", page.getTotalRow());
		root.put("rows", page.getList());
		renderJson(JsonKit.toJson(root));
    }

    public void save() {
        String tbName = getPara(0);
        if(tbName.equals("auth_org") ){
            //清除缓存
            CacheKit.removeAll("orguserTree");
        }
        Record rcd = paraToRecord("id");
        if (Db.save(tbName, rcd)) {
           // renderJson(Constants.SAVESUCCESS);
			render(new JsonRender(Constants.SAVESUCCESS).forIE());

        } else {
         //   renderJson(Constants.SAVEFAILED);
			render(new JsonRender(Constants.SAVEFAILED).forIE());

        }
    }

    public void update() {
        String tbName = getPara(0);
        if(tbName.equals("auth_org") ){
            //清除缓存
            CacheKit.removeAll("orguserTree");
        }
        Record rcd = paraToRecord("");
        if (Db.update(tbName, rcd)) {
          //  renderJson(Constants.EDITSUCCESS);
			render(new JsonRender(Constants.EDITSUCCESS).forIE());

        } else {
          //  renderJson(Constants.EDITFAILED);
			render(new JsonRender(Constants.EDITFAILED).forIE());

        }
    }

    public void delete() {
        String tbName = getPara(0);
        if(tbName.equals("auth_org") ){
            //清除缓存
            CacheKit.removeAll("orguserTree");
        }
        int id = getParaToInt(1);
        if (Db.deleteById(tbName, id)) {
          //  renderJson(Constants.DELETESUCCESS);
			render(new JsonRender(Constants.DELETESUCCESS).forIE());

        } else {
          //  renderJson(Constants.DELETEFAILED);
			render(new JsonRender(Constants.DELETEFAILED).forIE());

        }
    }

    /**
     * 临时解决方案，后续需要使用表结构处理
     * @param excludeField
     * @return
     */
    protected Record paraToRecord(String excludeField) {
        Map<String, String[]> map = getParaMap();
        Record rcd = new Record();
        for (Map.Entry<String, String[]> en : map.entrySet()) {
            if (StringKit.isBlank(en.getKey()) || (excludeField.length() > 0 && excludeField.equalsIgnoreCase(en.getKey()))) {
                continue;
            }
            String[] paraValue = en.getValue();
            Object value = StringKit.notBlank(paraValue[0])? paraValue[0] : null;//如果数据为空，则直接赋值null
            rcd.set(en.getKey(), value);
        }
        String userName = getAttr(Constants.USER_NAME);
        rcd.set("optname",userName);
        return rcd;
    }

    /**
     * 根据配置的外键关系，生成对应的下拉树组件url
     *
     * @param list
     * @return
     */
    protected List<Map<String, String>> buildFieldsFk(List<TableMeta> list) {
        List<Map<String, String>> fdsList = new ArrayList<Map<String, String>>();
        for (TableMeta t : list) {
            if (StringKit.notBlank(t.getFkTable()) && StringKit.notBlank(t.getFkId())
                    && StringKit.notBlank(t.getFkName())) {
                t.put("cmb",true);
                String fields = t.getFkId() + " as id," + t.getFkName() + " as text";
                String url = "common/comboTree";
                if (StringKit.notBlank(t.getFkWhere())) {
                    url += "/" + t.getFkWhere();
                }
                url += "?table=" + t.getFkTable() + "&fields=" + fields;
                url += "&pid=" + t.getFkPid() + "&pidStart=0&id=id";
                Map<String, String> map = new HashMap<String, String>();
                map.put("id", t.getFieldName());
                map.put("url", url);
                fdsList.add(map);
            }else{
                t.put("cmb",false);
            }
        }
        return fdsList;
    }
}
